#include <iostream>

using std::cout;
using std::endl;

class Point
{
public:
    Point(int ix = 0, int iy = 0)
    : _ix(ix)
    , _iy(iy)
    {
        cout << "Point(int = 0, int = 0)"  << endl;
    }

    void print() const
    {
        cout << "(" << _ix
             << ", " << _iy
             << ")" << endl;
    }

    ~Point()
    {
        cout << "~Point()" << endl;
    }
private:
    int _ix;
    int _iy;
};

template <typename  T>
class RAII
{
public:
    //1、在构造函数中初始化资源
    RAII(T *data)
    : _data(data)
    {
        cout <<"RAII(T *)" << endl;
    }

    //2、在析构函数中释放资源
    ~RAII()
    {
        cout << "~RAII()" << endl;
        if(_data)
        {
            delete _data;
            _data = nullptr;
        }
    }

    //3、提供若干访问资源的方法
    T *operator->()
    {
        return _data;
    }

    T &operator*()
    {
        return *_data;
    }

    T *get() const
    {
        return _data;
    }

    //重置
    void reset(T *data)
    {
        if(_data)
        {
            delete _data;
            _data = nullptr;
        }
        _data = data;
    }

    //4、不允许复制或者赋值
    RAII(const RAII &rhs) = delete;
    RAII &operator=(const RAII &rhs) = delete;
private:
    T *_data;
    /* int *_data; */
    /* double *_data; */
    /* string *_data; */
    /* Point *_data; */
};

void test()
{
    //利用栈对象的生命周期结束的时候，会执行析构函数，完成
    //资源的清理
    RAII<int> raii(new int(10));//栈对象raii

    cout << endl;
    //pt本身不是一个指针，但是pt的使用就与一个指针完全一样
    //可以托管资源（new int(10),new Point(1, 2)）,但是可以
    //不用直接执行delete就可以将资源进行回收,资源的回收靠的
    //就是栈对象pt的销毁执行析构函数
    RAII<Point> pt(new Point(1, 2));//栈对象pt
    pt->print();
    (*pt).print();
    /* pt.operator->()->print(); */
}

int main(int argc, char **argv)
{
    test();
    return 0;
}

